package com.xuecheng.learning.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.xuecheng.base.exception.XueChengPlusException;
import com.xuecheng.base.model.PageResult;
import com.xuecheng.content.model.po.CoursePublish;
import com.xuecheng.learning.feignclient.ContentServiceClient;
import com.xuecheng.learning.mapper.XcChooseCourseMapper;
import com.xuecheng.learning.mapper.XcCourseTablesMapper;
import com.xuecheng.learning.model.dto.MyCourseTableParams;
import com.xuecheng.learning.model.dto.XcChooseCourseDto;
import com.xuecheng.learning.model.dto.XcCourseTablesDto;
import com.xuecheng.learning.model.po.XcChooseCourse;
import com.xuecheng.learning.model.po.XcCourseTables;
import com.xuecheng.learning.service.MyCourseTablesService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.List;

@Service
@Slf4j
public class MyCourseTablesServiceImpl implements MyCourseTablesService {

    @Autowired
    private XcChooseCourseMapper chooseCourseMapper;

    @Autowired
    private XcCourseTablesMapper courseTablesMapper;

    @Autowired
    private ContentServiceClient contentServiceClient;

    /**
     * @param userId   用户id
     * @param courseId 课程id
     * @return com.xuecheng.learning.model.dto.XcChooseCourseDto
     * @description 添加选课
     * @author Mr.M
     * @date 2022/10/24 17:33
     */
    @Override
    @Transactional
    public XcChooseCourseDto addChooseCourse(String userId, Long courseId) {

        // 选课调用内容管理查询课程的收费规则
        CoursePublish coursepublish = contentServiceClient.getCoursepublish(courseId);
        if (coursepublish == null) {
            XueChengPlusException.cast("课程不存在");
        }

        // 收费规则
        String charge = coursepublish.getCharge();
        // 选课记录
        XcChooseCourse chooseCourse = null;
        if ("201000".equals(charge)) {
            // 如果是免费课程，会向选课记录表，我的课程表写数据
            chooseCourse = addFreeCoruse(userId, coursepublish); // 向选课记录表写
            // 向我的课程表写
            XcCourseTables xcCourseTables = addCourseTabls(chooseCourse);
        } else {
            // 如果收费课程，会向选课记录表写数据
            chooseCourse = addChargeCoruse(userId, coursepublish);
        }

        // 判断学生的学习资格
        XcCourseTablesDto courseTablesDto = getLearningStatus(userId, courseId);

        // 构造返回值
        XcChooseCourseDto chooseCourseDto = new XcChooseCourseDto();
        BeanUtils.copyProperties(chooseCourse, chooseCourseDto);

        // 设置学习资格状态
        chooseCourseDto.setLearnStatus(courseTablesDto.getLearnStatus());

        return chooseCourseDto;
    }

    /**
     * @description 判断学习资格
     * @param userId
     * @param courseId
     * @return XcCourseTablesDto 学习资格状态 [{"code":"702001","desc":"正常学习"},{"code":"702002","desc":"没有选课或选课后没有支付"},{"code":"702003","desc":"已过期需要申请续期或重新支付"}]
     * @author Mr.M
     * @date 2022/10/3 7:37
     */
    @Override
    public XcCourseTablesDto getLearningStatus(String userId, Long courseId) {

        XcCourseTablesDto courseTablesDto = new XcCourseTablesDto();

        // 查询我的课程表，如果查不到说明没有选课
        XcCourseTables xcCourseTables = getXcCourseTables(userId, courseId);
        if(xcCourseTables == null){
            courseTablesDto.setLearnStatus("702002");
            return courseTablesDto;
        }

        // 如果查到了，判断是否过期，如果过期不能继续学习，没有过期可以继续学习
        boolean before = xcCourseTables.getValidtimeEnd().isBefore(LocalDateTime.now());
        if(before) {
            BeanUtils.copyProperties(xcCourseTables, courseTablesDto);
            courseTablesDto.setLearnStatus("702003");
            return courseTablesDto;
        } else {
            BeanUtils.copyProperties(xcCourseTables, courseTablesDto);
            courseTablesDto.setLearnStatus("702001");
            return courseTablesDto;
        }
    }

    /**
     * 保存选课成功状态
     * @param chooseCourseId
     * @return
     */
    @Override
    @Transactional
    public boolean saveChooseCourseSuccess(String chooseCourseId) {

        // 根据选课id查询选课表
        XcChooseCourse chooseCourse = chooseCourseMapper.selectById(chooseCourseId);
        if(chooseCourse == null) {
            log.debug("接收到购买课程的消息，根据选课id从数据库找不到选课记录,选课id:{}", chooseCourseId);
            return false;
        }

        // 选课状态
        String status = chooseCourse.getStatus();
        // 只有当未支付时更新才已支付
        if("701002".equals(status)) {
            // 更新选课记录的状态为成功
            chooseCourse.setStatus("701001");
            int i = chooseCourseMapper.updateById(chooseCourse);
            if(i <= 0) {
                log.debug("添加选课记录失败:{}", chooseCourse);
                XueChengPlusException.cast("添加选课记录失败");
            }

            // 向我的课程表插入记录
            addCourseTabls(chooseCourse);
        }
        return true;
    }

    /**
     * @description 我的课程表
     * @param params
     * @return com.xuecheng.base.model.PageResult<com.xuecheng.learning.model.po.XcCourseTables>
     * @author Mr.M
     * @date 2022/10/27 9:24
     */
    @Override
    public PageResult<XcCourseTables> mycoursetables(MyCourseTableParams params) {

        // 用户id
        String userId = params.getUserId();
        // 当前页码
        Long pageNo = params.getPage();
        // 每页记录数
        Long size = params.getSize();

        Page<XcCourseTables> courseTablesPage = new Page<>(pageNo, size);
        LambdaQueryWrapper<XcCourseTables> lambdaQueryWrapper = new LambdaQueryWrapper<XcCourseTables>().eq(XcCourseTables::getUserId, userId);

        // 查询数据
        Page<XcCourseTables> result = courseTablesMapper.selectPage(courseTablesPage, lambdaQueryWrapper);

        // 数据列表
        List<XcCourseTables> records = result.getRecords();
        // 总记录数
        long total = result.getTotal();

        PageResult pageResult = new PageResult(records, total, pageNo, size);
        return pageResult;
    }

    //添加免费课程,免费课程加入选课记录表、我的课程表
    private XcChooseCourse addFreeCoruse(String userId, CoursePublish coursepublish) {

        // 课程id
        Long courseId = coursepublish.getId();

        // 判断如果存在免费的选课记录且选择状态为成功，直接返回了
        LambdaQueryWrapper<XcChooseCourse> queryWrapper = new LambdaQueryWrapper<XcChooseCourse>()
                .eq(XcChooseCourse::getUserId, userId)
                .eq(XcChooseCourse::getCourseId, courseId)
                .eq(XcChooseCourse::getOrderType, "700001") // 免费课程
                .eq(XcChooseCourse::getStatus, "701001"); // 选课成功
        List<XcChooseCourse> chooseCourses = chooseCourseMapper.selectList(queryWrapper);
        if (chooseCourses.size() > 0) {
            return chooseCourses.get(0);
        }

        // 向选课记录表写数据
        XcChooseCourse chooseCourse = new XcChooseCourse();
        chooseCourse.setCourseId(courseId);
        chooseCourse.setCourseName(coursepublish.getName());
        chooseCourse.setUserId(userId);
        chooseCourse.setCompanyId(coursepublish.getCompanyId());
        chooseCourse.setOrderType("700001"); // 免费课程
        chooseCourse.setCreateDate(LocalDateTime.now());
        chooseCourse.setCoursePrice(coursepublish.getPrice());
        chooseCourse.setCoursePrice(coursepublish.getPrice());
        chooseCourse.setValidDays(365);
        chooseCourse.setStatus("701001"); // 选课成功
        chooseCourse.setValidtimeStart(LocalDateTime.now()); // 有效期的开始时间
        chooseCourse.setValidtimeEnd(LocalDateTime.now().plusDays(365)); // 有效期的结束时间
        int insert = chooseCourseMapper.insert(chooseCourse);
        if (insert <= 0) {
            XueChengPlusException.cast("添加选课记录失败");
        }

        return chooseCourse;
    }

    //添加到我的课程表
    private XcCourseTables addCourseTabls(XcChooseCourse xcChooseCourse) {

        // 选课成功了才可以向我的课程表添加
        String status = xcChooseCourse.getStatus();
        if (!"701001".equals(status)) {
            XueChengPlusException.cast("选课没有成功无法添加到课程表");
        }

        XcCourseTables xcCourseTables = getXcCourseTables(xcChooseCourse.getUserId(), xcChooseCourse.getCourseId());
        if(xcCourseTables != null) {
            return xcCourseTables;
        }

        xcCourseTables = new XcCourseTables();
        BeanUtils.copyProperties(xcChooseCourse, xcCourseTables);
        xcCourseTables.setChooseCourseId(xcChooseCourse.getId()); // 记录选课表的主键
        xcCourseTables.setCourseType(xcCourseTables.getCourseType()); // 选课类型
        xcCourseTables.setUpdateDate(LocalDateTime.now());
        int insert = courseTablesMapper.insert(xcCourseTables);
        if(insert <= 0) {
            XueChengPlusException.cast("添加我的课程表失败");
        }

        return xcCourseTables;
    }

    //添加收费课程
    private XcChooseCourse addChargeCoruse(String userId, CoursePublish coursepublish) {

        // 课程id
        Long courseId = coursepublish.getId();

        // 判断如果存在收费的选课记录且选择状态为待支付，直接返回了
        LambdaQueryWrapper<XcChooseCourse> queryWrapper = new LambdaQueryWrapper<XcChooseCourse>()
                .eq(XcChooseCourse::getUserId, userId)
                .eq(XcChooseCourse::getCourseId, courseId)
                .eq(XcChooseCourse::getOrderType, "700002") // 收费课程
                .eq(XcChooseCourse::getStatus, "701002"); // 待支付
        List<XcChooseCourse> chooseCourses = chooseCourseMapper.selectList(queryWrapper);
        if (chooseCourses.size() > 0) {
            return chooseCourses.get(0);
        }

        // 向选课记录表写数据
        XcChooseCourse chooseCourse = new XcChooseCourse();
        chooseCourse.setCourseId(courseId);
        chooseCourse.setCourseName(coursepublish.getName());
        chooseCourse.setUserId(userId);
        chooseCourse.setCompanyId(coursepublish.getCompanyId());
        chooseCourse.setOrderType("700002"); // 收费课程
        chooseCourse.setCreateDate(LocalDateTime.now());
        chooseCourse.setCoursePrice(coursepublish.getPrice());
        chooseCourse.setCoursePrice(coursepublish.getPrice());
        chooseCourse.setValidDays(365);
        chooseCourse.setStatus("701002"); // 待支付
        chooseCourse.setValidtimeStart(LocalDateTime.now()); // 有效期的开始时间
        chooseCourse.setValidtimeEnd(LocalDateTime.now().plusDays(365)); // 有效期的结束时间
        int insert = chooseCourseMapper.insert(chooseCourse);
        if (insert <= 0) {
            XueChengPlusException.cast("添加选课记录失败");
        }

        return chooseCourse;
    }

    /**
     * @param userId
     * @param courseId
     * @return com.xuecheng.learning.model.po.XcCourseTables
     * @description 根据课程和用户查询我的课程表中某一门课程
     * @author Mr.M
     * @date 2022/10/2 17:07
     */
    private XcCourseTables getXcCourseTables(String userId, Long courseId) {
        XcCourseTables xcCourseTables = courseTablesMapper.selectOne(new LambdaQueryWrapper<XcCourseTables>().eq(XcCourseTables::getUserId, userId).eq(XcCourseTables::getCourseId, courseId));
        return xcCourseTables;

    }
}
